package cc.rengu.igas.bsps.core.service.trans;

import cc.rengu.igas.bsps.common.dao.BspsMchntOrderInfoMapper;
import cc.rengu.igas.bsps.common.dao.TradeDetailInfoMapper;
import cc.rengu.igas.bsps.common.dao.impl.BspsMchntOrderInfoMapperImpl;
import cc.rengu.igas.bsps.common.dao.impl.TradeDetailInfoMapperImpl;
import cc.rengu.igas.bsps.common.entity.MchntBindInfo;
import cc.rengu.igas.bsps.common.enums.BspsUserRoleTypeEnum;
import cc.rengu.igas.bsps.common.enums.RespCodeEnum;
import cc.rengu.igas.bsps.core.service.base.ManageService;
import cc.rengu.igas.bsps.facade.bean.TradeStatisInfoBean;
import cc.rengu.igas.bsps.facade.request.CurrentTransStatisInfoQueryRequest;
import cc.rengu.igas.bsps.facade.response.CurrentTransStatisInfoQueryResponse;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;
import org.springframework.util.CollectionUtils;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 当日收款信息查询.
 */
public class CurrentTransStatisInfoQueryService extends ManageService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        CurrentTransStatisInfoQueryRequest currentTransStatisInfoQueryRequest = new CurrentTransStatisInfoQueryRequest();
        ConvertUtil.convertOutput(currentTransStatisInfoQueryRequest);
        return currentTransStatisInfoQueryRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        BizResponse<CurrentTransStatisInfoQueryResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        CurrentTransStatisInfoQueryRequest currentTransStatisInfoQueryRequest = (CurrentTransStatisInfoQueryRequest) request;
        String instId = currentTransStatisInfoQueryRequest.getHeader().getInstId();
        String mchntNo = currentTransStatisInfoQueryRequest.getMchntNo();
        String userId = currentTransStatisInfoQueryRequest.getUserId();
        String startDate = currentTransStatisInfoQueryRequest.getStartDate();
        String endDate = currentTransStatisInfoQueryRequest.getEndDate();

        if (StringUtil.isEmptyOrNull(startDate)) {
            startDate = DateUtil.getCurrentDateTime("yyyyMMdd");
        }
        if (StringUtil.isEmptyOrNull(endDate)) {
            endDate = DateUtil.getCurrentDateTime("yyyyMMdd");
        }

        CurrentTransStatisInfoQueryResponse currentTransStatisInfoQueryResponse = new CurrentTransStatisInfoQueryResponse();
        //获取用户权限
        String key = userId + mchntNo;
        MchntBindInfo mchntBindInfo = JSON.parseObject(RedisUtil.onceGet(key), MchntBindInfo.class);

        String refundTotalAmt = "0";
        String refundTotalNum = "0";
        String payTotalAmt = "0";
        String payTotalNum = "0";
        List<MchntOrderInfo> allMchntOrderInfoList;
        BspsMchntOrderInfoMapper bspsMchntOrderInfoMapper = new BspsMchntOrderInfoMapperImpl();
        if (mchntBindInfo != null && BspsUserRoleTypeEnum.MCHNT_CASHIER.getRoleType().equals(mchntBindInfo.getBindUserRole())) {
            /* 用户角色为收银员时，按只查该用户的交易数据 */
            allMchntOrderInfoList = bspsMchntOrderInfoMapper.selectBspsMchntOrderInfoByMchntNoAndUserId(instId, mchntNo, startDate, endDate, userId, TransStatusEnum.TRANS_SUCC.getStatus());
        } else {
            /* 其他角色可查询所有订单数据 */
            allMchntOrderInfoList = bspsMchntOrderInfoMapper.selectBspsMchntOrderInfoByMchntNo(instId, mchntNo, startDate, endDate, TransStatusEnum.TRANS_SUCC.getStatus());
        }

        if (CollectionUtils.isEmpty(allMchntOrderInfoList)) {
            rglog.info("当日没有收款数据，商户号:{},用户id：{}", mchntNo, userId);
            currentTransStatisInfoQueryResponse.setPayTotalAmt(payTotalAmt);
            currentTransStatisInfoQueryResponse.setPayTotalNum(payTotalNum);
            currentTransStatisInfoQueryResponse.setRefundTotalAmt(refundTotalAmt);
            currentTransStatisInfoQueryResponse.setRefundTotalNum(refundTotalNum);
            bizResponse.setResult(currentTransStatisInfoQueryResponse);
            return bizResponse;
        }

        List<PayOrderInfo> allPayOrderInfoList = new ArrayList<>();
        List<PayOrderInfo> payOrderList = new ArrayList<>();
        List<PayOrderInfo> refundOrderList = new ArrayList<>();

        for (MchntOrderInfo item : allMchntOrderInfoList) {
            String txnNum = item.getTxnNum();
            if (item.getTxnNum().startsWith("P04") || item.getTxnNum().startsWith("P03")) {
                refundTotalAmt = AmountUtil.addition(refundTotalAmt, item.getOrderAmt());
                refundTotalNum = AmountUtil.addition(refundTotalNum, "1");
            } else {
                payTotalAmt = AmountUtil.addition(payTotalAmt, item.getOrderAmt());
                payTotalNum = AmountUtil.addition(payTotalNum, "1");
            }

            TradeDetailInfoMapper tradeDetailInfoMapper = new TradeDetailInfoMapperImpl();
            List<PayOrderInfo> payOrderInfoList = tradeDetailInfoMapper.bspsSelectPayOrderInfoBySysSeqNum(instId, item.getSysSeqNum());
            if (CollectionUtils.isEmpty(payOrderInfoList)) {
                rglog.error("商户订单表存在记录，支付订单表不存在记录！instId:<{}>,SysSeqNum:<{}>", instId, item.getSysSeqNum());
                continue;
//                throw new BizException(RespCodeEnum.RECORD_NOT_FOUND.getRespCode(), "商户订单表存在记录，支付订单表不存在记录");
            }
            payOrderInfoList.get(0).setOrderAmt(item.getOrderAmt());
            String txnNumb = payOrderInfoList.get(0).getTxnNum();
            if (txnNumb.startsWith("P04") || txnNumb.startsWith("P03")) {
                refundOrderList.add(payOrderInfoList.get(0));
            } else {
                payOrderList.add(payOrderInfoList.get(0));
            }
            allPayOrderInfoList.add(payOrderInfoList.get(0));
        }

        Map<String, TradeStatisInfoBean> payTypeMap = new HashMap<>();
        //for (PayOrderInfo item : allPayOrderInfoList) {
        for (int i = 0; i < allPayOrderInfoList.size(); i++) {
            PayOrderInfo item = allPayOrderInfoList.get(i);
            String txnNum = item.getTxnNum();
            String txn = txnNum.substring(1, 3);
            //存在key
            if (payTypeMap.containsKey(item.getPayType())) {
                TradeStatisInfoBean tradeStatisInfoBean = payTypeMap.get(item.getPayType());
                if (item.getTxnNum().startsWith("P04") || item.getTxnNum().startsWith("P03")) {
                    tradeStatisInfoBean.setRefundAmt(AmountUtil.addition(tradeStatisInfoBean.getRefundAmt(), item.getOrderAmt()));
                    tradeStatisInfoBean.setRefundNum(AmountUtil.addition(tradeStatisInfoBean.getRefundNum(), "1"));
                } else {
                    tradeStatisInfoBean.setPayAmt(AmountUtil.addition(tradeStatisInfoBean.getPayAmt(), item.getOrderAmt()));
                    tradeStatisInfoBean.setPayNum(AmountUtil.addition(tradeStatisInfoBean.getPayNum(), "1"));
                }
                // 计算占比
                if (allPayOrderInfoList.size() - 1 == i) {
                    if (payOrderList.size() != 0) {
                        String payRatio = getRatio(tradeStatisInfoBean.getPayNum(), String.valueOf(payOrderList.size()), "00");
                        tradeStatisInfoBean.setPayRatio(payRatio);
                    }
                    if (refundOrderList.size() != 0) {
                        String refundRatio = getRatio(tradeStatisInfoBean.getRefundNum(), String.valueOf(refundOrderList.size()), "00");
                        tradeStatisInfoBean.setRefundRatio(refundRatio);
                    }

                    payTypeMap.put(item.getPayType(), tradeStatisInfoBean);
                } else {
                    if (payOrderList.size() != 0) {
                        String payRatio = getRatio(tradeStatisInfoBean.getPayNum(), String.valueOf(payOrderList.size()), "01");
                        tradeStatisInfoBean.setPayRatio(payRatio);
                    }
                    if (refundOrderList.size() != 0) {
                        String refundRatio = getRatio(tradeStatisInfoBean.getRefundNum(), String.valueOf(refundOrderList.size()), "01");
                        tradeStatisInfoBean.setRefundRatio(refundRatio);
                    }
                    payTypeMap.put(item.getPayType(), tradeStatisInfoBean);
                }


            } else {
                TradeStatisInfoBean tradeStatisInfoBean = new TradeStatisInfoBean();
                tradeStatisInfoBean.setPayType(item.getPayType());
                //TODO 待定
                if (item.getTxnNum().startsWith("P04") || item.getTxnNum().startsWith("P03")) {
                    tradeStatisInfoBean.setRefundAmt(item.getOrderAmt());
                    tradeStatisInfoBean.setRefundNum("1");
                    if (allPayOrderInfoList.size() - 1 == i) {
                        String refundRatio = getRatio(tradeStatisInfoBean.getRefundNum(), String.valueOf(refundOrderList.size()), "00");
                        tradeStatisInfoBean.setRefundRatio(refundRatio);
                    } else {
                        String refundRatio = getRatio(tradeStatisInfoBean.getRefundNum(), String.valueOf(refundOrderList.size()), "01");
                        tradeStatisInfoBean.setRefundRatio(refundRatio);
                    }

                    tradeStatisInfoBean.setPayAmt("0");
                    tradeStatisInfoBean.setPayNum("0");
                    tradeStatisInfoBean.setPayRatio("0");
                } else {
                    tradeStatisInfoBean.setPayAmt(item.getOrderAmt());
                    tradeStatisInfoBean.setPayNum("1");
                    if (allPayOrderInfoList.size() - 1 == i) {
                        String payRatio = getRatio(tradeStatisInfoBean.getPayNum(), String.valueOf(payOrderList.size()), "00");
                        tradeStatisInfoBean.setPayRatio(payRatio);
                    } else {
                        String payRatio = getRatio(tradeStatisInfoBean.getPayNum(), String.valueOf(payOrderList.size()), "01");
                        tradeStatisInfoBean.setPayRatio(payRatio);
                    }

                    tradeStatisInfoBean.setRefundAmt("0");
                    tradeStatisInfoBean.setRefundNum("0");
                    tradeStatisInfoBean.setRefundRatio("0");
                }

                payTypeMap.put(item.getPayType(), tradeStatisInfoBean);
            }
        }
        List<TradeStatisInfoBean> TradeStatisInfoBeanList = new ArrayList<TradeStatisInfoBean>();
        for (String keyb : payTypeMap.keySet()) {
            TradeStatisInfoBeanList.add(payTypeMap.get(keyb));
        }
        currentTransStatisInfoQueryResponse.setPayTotalAmt(payTotalAmt);
        currentTransStatisInfoQueryResponse.setPayTotalNum(payTotalNum);
        currentTransStatisInfoQueryResponse.setRefundTotalAmt(refundTotalAmt);
        currentTransStatisInfoQueryResponse.setRefundTotalNum(refundTotalNum);
        currentTransStatisInfoQueryResponse.setTradeStatisInfoBeanList(TradeStatisInfoBeanList);

        /* 拼装响应结果 */

        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(currentTransStatisInfoQueryResponse);
        return bizResponse;
    }

    /**
     * 返回占比 （最后一条进行剪发）
     * type 00 最后一条 01中间条
     *
     * @return 占比
     */
    private String getRatio(String num, String total, String type) {
        NumberFormat numberFormat = NumberFormat.getInstance();
        numberFormat.setMaximumFractionDigits(2);
        if ("00".equals(type)) {
            String nums = AmountUtil.subtraction(total, num);

            String ratio = numberFormat.format(Float.valueOf(nums) / Float.valueOf(total) * 100);
            return AmountUtil.subtraction("100", ratio);
        }
        return numberFormat.format(Float.valueOf(num) / Float.valueOf(total) * 100);
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        CurrentTransStatisInfoQueryResponse currentTransStatisInfoQueryResponse = (CurrentTransStatisInfoQueryResponse) bizResponse.getResult();
        ConvertUtil.convertInput(currentTransStatisInfoQueryResponse);
    }
}
